package com.mephi.oshs.presenter;

import com.mephi.oshs.model.entry.IEntry;
import com.mephi.oshs.model.interpreter.api.IContext;
import com.mephi.oshs.model.interpreter.api.IExpression;
import com.mephi.oshs.model.tree.OshsTree;
import com.mephi.oshs.view.api.IOshsView;
import com.mephi.oshs.view.api.ISearchView;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

public class SearchPresenter extends AbstractPresenter {

    private static final Logger logger = LoggerFactory.getLogger(SearchPresenter.class);

    private IExpression searchExpression = null;

    private int expressionSearchEntryIndex = 0;

    private int expressionSearchEntryPosition = 0;

    private final List<IEntry> expressionSearchEntryList = new ArrayList<IEntry>();

    @Override
    public void bind() {
        final ISearchView searchView = this.getSearchView();

        searchView.getExpressionSearchAction().addClickListener(new Listener() {

            @Override
            public void handleEvent(Event event) {
                onExpressionSearch();
            }
        });
    }

    @Override
    public void unbind() {
        throw new RuntimeException("unbind(): Not implemented yet.");
    }

    private void onExpressionSearch() {
        final OshsTree<IEntry> oshsTree = OshsTree.getInstance();
        final ISearchView searchView = this.getSearchView();
        final IOshsView oshsView = this.getOshsView();

        // Создаем пустой контекст.
        final IContext ctx = searchView.getSearchContext();

        // Создаем ключ-элемент.
        final Object key = searchView.getObjectKey();

        // Создаем поисковое выражение.
        final IExpression expr = searchView.getSearchExpression();

        // New search request.
        if (this.searchExpression == null || !this.searchExpression.equals(expr)) {
            this.searchExpression = expr;
            this.expressionSearchEntryIndex = 0;
            this.expressionSearchEntryPosition = 0;
            this.expressionSearchEntryList.clear();

            // Выполняем поисковое выражение.
            final List<IEntry> searchResults = oshsTree.getEntriesMatchingExpression(expr, ctx, key);
            this.expressionSearchEntryList.addAll(searchResults);
        }

        // Select next entry.
        while (this.expressionSearchEntryIndex < this.expressionSearchEntryList.size()) {
            if (oshsView.getOshsTreeWidget().selectEntry(expressionSearchEntryList.get(this.expressionSearchEntryIndex),
                    this.expressionSearchEntryPosition)) {
                this.expressionSearchEntryPosition++;
                return;
            } else {
                this.expressionSearchEntryIndex++;
                this.expressionSearchEntryPosition = 0;
            }
        }

        // Restore indexes - return to the first entry.
        this.expressionSearchEntryIndex = 0;
        this.expressionSearchEntryPosition = 0;
        oshsView.getOshsTreeWidget().deselectAll();

        logger.debug("Expression search found nothing.");
    }
}
